package Network

import (
	"SQL/FSDB"
	"database/sql"
	"encoding/json"
	"logs"

	"fmt"

	"github.com/gorilla/websocket"
)

/*
websocket通讯过程概要：
	1.login
	2.addClient
	3.deleteClient (掉线)
	4.close (同账号登录)
*/

type ClientRequest struct {
	Method string      `json:"Method"`
	Args   interface{} `json:"Args"`
}

type ServerResponse struct {
	Method  string      `json:"Method"`
	Code    int         `json:"Code"`
	Message string      `json:"Message"`
	Result  interface{} `json:"Result"`
}

var msgDispatchChan = make(chan ServerResponse)
var upgrader = websocket.Upgrader{}

// --------------------------------------------- 连接创建、消息创建部分
// wsLogin 初始化WebSocket连接，
// 				 每个客户端都需要连接/ws接口以建立WebSocket连接

// 客户端的消息发送循环
func processClientMsg(clientID string, ws *websocket.Conn) {

	for {
		var clientMsg ClientRequest
		err := ws.ReadJSON(&clientMsg)
		if err != nil {
			logs.Print("clientID:", clientID, "DISCONNECTED!\nerr:", err.Error())
			deleteClient(clientID)
			break
		}
		go wsRouter(clientID, clientMsg)
		tx, db, err := FSDB.BeginTx()
		if err != nil {
			closeDB(db)
			return
		}
		err = updateUserOnlineTime(tx, clientID, currentTime())
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
		closeDB(db)
	}
}

// 更新当前用户的在线时间
func updateUserOnlineTime(tx *sql.Tx, ID string, time string) error {
	// logs.Print("User:", ID, " onlineTime:", time)
	updateTimeSQL := `UPDATE users
					  SET lastOnlineTime = $1
					  WHERE id = $2`
	_, err := FSDB.ExecTx(tx, updateTimeSQL, time, ID)
	if err != nil {
		logs.PrintParent("updateUserOnlineTime Exec，err:", err.Error())
		return err
	}
	return nil
}

// --------------------------------------------- 消息分发部分

// 将系统消息发送给当前用户
func dispatchSystemMsgToClient(clientID string, method string, errCode int, errMsg string) error {

	res := &ServerResponse{
		Method:  method,
		Code:    errCode,
		Message: errMsg,
		Result:  nil,
	}
	err := writeResponseToClient(clientID, res)
	if err != nil {
		return err
	}
	return nil
}

// 将普通消息发送给当前客户端
func writeResponseToClient(clientID string, res *ServerResponse) error {

	lockk <- true
	clientData, ok := wsClients[clientID]
	client := clientData.conn
	if !ok {
		<-lockk
		return fmt.Errorf("用户：%s尚未登录！", clientID)
	}

	JSON, err := json.MarshalIndent(res, "", " ")
	if err != nil {
		<-lockk
		return err
	}
	err = client.WriteMessage(1, JSON)
	<-lockk
	//err := client.WriteJSON(res)
	if err != nil {
		logs.Print(clientID, "DISCONNECTED!\n err:", err.Error())
		//client.Close()		----------------------deleteClient里Close了,对wsClient的操作都写在函数里面
		deleteClient(clientID)
		return err
	}
	return nil
}

// 将普通消息发送给群组
func writeResponseToGroup(senderID string, groupID string, time string, newMsg ServerResponse) error {

	groupMemberSQL := `SELECT userid AS memberID FROM members WHERE groupid=$1 AND userid <> $2`
	members, err := FSDB.Query(groupMemberSQL, groupID, senderID)
	defer members.Close()

	if err != nil {
		logs.Print("sendMsgToGroup Query FAILED!\nerr:", err.Error())
		return err
	}

	for members.Next() {
		var id int64
		err := members.Scan(&id)
		memberID := fmt.Sprintf("%v", id)

		if err != nil {
			logs.Print("sendMsgToGroup members.Scan() FAILED!\nerr:", err.Error())
			return err
		}
		go func() {
			writeResponseToClient(memberID, &newMsg)
		}()
	}
	return nil
}
